package net.cmkj.mine.bean;

import com.google.common.collect.Lists;
import com.jfinal.aop.Before;
import com.jfinal.kit.JsonKit;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.tx.Tx;
import net.cmkj.mine.bean.base.BaseSysUser;
import net.cmkj.mine.common.cache.CacheClearUtils;
import net.cmkj.mine.common.model.Condition;
import net.cmkj.mine.common.model.InvokeResult;
import net.cmkj.mine.common.model.Operators;
import net.cmkj.mine.common.model.ZtreeView;
import net.cmkj.mine.util.CommonUtils;
import net.cmkj.mine.util.MyDigestUtils;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.*;

/**
 * Generated by JFinal.
 */
@SuppressWarnings("serial")
public class SysUser extends BaseSysUser<SysUser> {

	public static final SysUser dao = new SysUser().dao();
	
	private static Logger log = LogManager.getLogger(SysUser.class);
	
	/**
	 * 获取列表
	 * @param pageNumber
	 * @param pageSize
	 * @param name
	 * @param status
	 * @return
	 */
	public Page<SysUser> paginate(int pageNumber, int pageSize, String name, String username, Integer status, String orderbyStr) throws Exception {
		log.info("获取列表");
		List<Object> params = new ArrayList<Object>();
		//String select = "select su.*, (select group_concat(name) as roleNames from sys_role where id in(select role_id from sys_user_role where user_id=su.id)) as roleNames ,d.`name` as deptname ";
		String select = "select su.*, (select group_concat(name) as roleNames from sys_role where id in(select role_id from sys_user_role where user_id=su.id)) as roleNames ";
		//StringBuffer sqlExceptSelect=new StringBuffer("from sys_user su  LEFT JOIN sys_dept d on su.deptid = d.id where 1=1");
		StringBuffer sqlExceptSelect=new StringBuffer("from sys_user su  where 1=1");
		if(CommonUtils.isNotEmpty(name)){
			sqlExceptSelect.append(" and su.name like ? ");
			params.add("%"+name+"%");
		}
		if(CommonUtils.isNotEmpty(username)){
			sqlExceptSelect.append(" and su.username like ? ");
			params.add("%"+username+"%");
		}
		if(status != null){
			sqlExceptSelect.append(" and su.status = ? ");
			params.add(status);
		}
		sqlExceptSelect.append(" "+orderbyStr);
		return dao.paginate(pageNumber, pageSize, select, sqlExceptSelect.toString(), CommonUtils.listToArr(params));
	}
	
	/**
	 * 获取对象
	 * @param id
	 * @return
	 */
	public SysUser findUserById(long id) throws Exception {
		log.info("获取对象");
		return dao.findFirst("select su.*,d.`name` as deptname  from sys_user su LEFT JOIN sys_dept d on su.deptid = d.id where su.id=?", id);
	}

	public Set<String> getPermissionSets() {
		return SysRes.dao.getSysUserAllResUrl(this.getId());
	}
	
	/**
	 * 是否有管理员权限
	 */
	public boolean isAdmin(){
		long count = Db.queryLong("select count(*) from sys_user_role where role_id=? and user_id=?", 1,this.getId());
		return  count>0?true:false;
	}
	
	public String getRoleStr(int userid) {
		return Db.queryStr("select (select group_concat(id) as roleNames from sys_role where id in(select role_id from sys_user_role where user_id=su.id)) as roleNames from sys_user su where su.id = ?", userid);
	}
	
	/**
	 * 用户名是否已存在
	 */
	public boolean hasExist(String name){
		Set<Condition> conditions=new HashSet<Condition>();
		conditions.add(new Condition("name",Operators.EQ,name));
		long num=this.getCount(conditions);
		return num>0?true:false;
	}
	
	/**
	 * 通过用户名获取用户信息
	 * @param name
	 * @return
	 */
	public SysUser getByName(String name){
		String sql = "select su.*, (select group_concat(name) as roleNames from sys_role where id in(select role_id from sys_user_role where user_id=su.id)) as roleNames from sys_user su where su.name = ?";
		/*Set<Condition> conditions=new HashSet<Condition>();
		conditions.add(new Condition("name",Operators.EQ,name));
		return this.get(conditions);*/
		return dao.findFirst(sql, name);
	}
	
	/**
	 * 用户登陆
	 */
	public InvokeResult login(String username, String pwd,HttpServletResponse response,HttpSession session,String url) {
		Set<Condition> conditions=new HashSet<Condition>();
		conditions.add(new Condition("name",Operators.EQ,username));
		conditions.add(new Condition("pwd",Operators.EQ, MyDigestUtils.hash(MyDigestUtils.hash(pwd))));
		SysUser sysUser=this.get(conditions);
		if(sysUser==null){
			return InvokeResult.failure("用户名或密码不对");
		}
		if(sysUser.getInt("status")==2){
			return InvokeResult.failure("用户被冻结，请联系管理员");
		}
		Map<String,Object> data=new HashMap<String,Object>();
		data.put("url",url);
		return InvokeResult.success(data);
	}

    /**
     * 对象保存
     * @param id
     * @param name
     * @param username
     * @param password
     * @param phone
     * @param email
     * @param deptid
     * @param des
     * @return
     * @throws Exception
     */
	/*@Before(Tx.class)
	public InvokeResult save(Integer id, String name, String username, String password, String phone, String email, Integer deptid, String des) throws Exception {
		log.info("对象保存");
		if(null!=id){
			SysUser sysUser=this.findById(id);
			sysUser.set("username", username).set("des", des).set("phone", phone).set("email", email).set("deptid", deptid).update();
		}else {
			if(this.hasExist(name)){
				return InvokeResult.failure("用户名已存在");
			}else {
				if(StrKit.isBlank(password))password="123456";
				SysUser sysUser=new SysUser();
				sysUser.set("name", name).set("username", username).set("pwd", MyDigestUtils.hash(MyDigestUtils.hash(password))).set("createdate", new Date()).set("des", des).set("phone", phone).set("email", email).set("deptid", deptid).save();
			}
		}
		return InvokeResult.success();
	}*/

	/**
	 * 对象保存
	 * @param id
	 * @param name
	 * @param username
	 * @param password
	 * @param phone
	 * @param email
	 * @param deptids
	 * @param deptnames
	 * @param des
	 * @return
	 * @throws Exception
	 */
	@Before(Tx.class)
	public InvokeResult save(Integer id, String name, String username, String password, String phone, String email, String deptids, String deptnames, String des) throws Exception {
		log.info("对象保存");
		if(null!=id){
			SysUser sysUser=this.findById(id);
			sysUser.set("username", username).set("des", des).set("phone", phone).set("email", email).set("deptids", deptids).set("deptnames", deptnames).update();
		}else {
			if(this.hasExist(name)){
				return InvokeResult.failure("用户名已存在");
			}else {
				if(StrKit.isBlank(password))password="123456";
				SysUser sysUser=new SysUser();
				sysUser.set("name", name).set("username", username).set("pwd", MyDigestUtils.hash(MyDigestUtils.hash(password))).set("createdate", new Date()).set("des", des).set("phone", phone).set("email", email).set("deptids", deptids).set("deptnames", deptnames).save();
			}
		}
		return InvokeResult.success();
	}
	
	/**
	 * 修改用户角色
	 */
	public InvokeResult changeUserRoles(Integer uid,String roleIds){
		Db.update("delete from sys_user_role where user_id = ?", uid);
		List<String> sqlList = Lists.newArrayList();
		for(String roleId : roleIds.split(",")){
			if(CommonUtils.isNotEmpty(roleId)){
				sqlList.add("insert into sys_user_role (user_id,role_id) values ("+uid+","+Integer.valueOf(roleId)+")");
			}
		}
		Db.batch(sqlList, 5);
		CacheClearUtils.clearUserMenuCache();
		return InvokeResult.success();
	};
	
	/**
	 * 密码修改
	 */
	public InvokeResult savePwdUpdate(Integer uid, String newPwd) {
		SysUser sysUser = this.findById(uid);
		if(sysUser != null){
			sysUser.set("pwd", newPwd).setPwdstate(1).update();
			return InvokeResult.success();
		}else{
			return InvokeResult.failure("修改失败");
		}
	}
	
	public InvokeResult setVisible(Integer id, Integer visible) throws Exception {
		SysUser sysUser=findById(id);
		sysUser.set("status", visible).update();
		return InvokeResult.success();
	}
	
	/**
	 * 对象删除
	 * @param ids
	 * @return
	 */
	@Before(Tx.class)
	public InvokeResult deleteByIds(String ids) throws Exception{
		log.info("对象删除");
    	String idarr[] = ids.split(",");
    	for (String id : idarr) {
    		if (!dao.findById(id).delete()) {
    			log.error("批量删除失败！");
    			throw new RuntimeException(id+"批量删除失败");
    		}
    	}
    	return InvokeResult.success();
	}
	
	/**
	 * 修改对象状态
	 * @param ids
	 * @return
	 */
	@Before(Tx.class)
	public InvokeResult setStatus(String ids, Integer status) throws Exception{
		log.info("对象状态变更");
		String idarr[] = ids.split(",");
    	for(String id : idarr){
    		if (!dao.findById(id).set("status", status).update()) {
    			log.error("对象批量状态变更失败！");
    			throw new RuntimeException(id+"状态批量变更失败！");
    		}
		}
		return InvokeResult.success();
	}

	public List<Record> getData(Integer moduleid ) throws Exception{
        Modules module = Modules.dao.findById(moduleid);
        int resid = 0;
        if(module!=null){
            resid =module.getSysres();
        }
		//return Db.find("SELECT u.id,u.username as name  FROM sys_user_role ro LEFT JOIN sys_user u ON u.id = ro.user_id where ro.role_id in (select role_id from sys_role_res rr where rr.res_id = "+resid+") and u.id not in (select user FROM module_user where module = "+moduleid+")");
		return Db.find("SELECT distinct u.id,u.username as name  FROM sys_user_role ro LEFT JOIN sys_user u ON u.id = ro.user_id where u.status = 1 and u.id !=1 and u.id not in (select user FROM module_user where module = "+moduleid+")");
	}

	public List<Record> getDataOne(Integer userid ) throws Exception{
		return Db.find("SELECT u.id,u.username as name  FROM sys_user u where u.status = 1 and u.id = ?",userid);
	}

	public List<Record> getUserAll() throws Exception{
		return Db.find("SELECT u.id,u.username as name  FROM sys_user u where u.status = 1 and u.id !=1 ");
	}

	public InvokeResult getZtreeViewList(Integer type, Integer resid) {
		List<Record> curMenulist = this.getDeptUser(resid);
		List<ZtreeView> ztreeViews = new ArrayList<ZtreeView>();
		ztreeViews.add(new ZtreeView(10000,null,"全公司",true));
		for(Record user : curMenulist){
			if (!"admin".equals(user.getStr("name"))) {
				ZtreeView ztreeView=new ZtreeView();
				ztreeView.setId(user.get("id"));
				ztreeView.setName(user.getStr("name"));
				ztreeView.setOpen(true);
				if(user.get("pid")==null){
					ztreeView.setpId(10000);
				}else{
					ztreeView.setpId(user.getStr("pid").split(",")[0]);
				}
				ztreeView.setChecked(user.getInt("selected")==1?true:false);
				ztreeViews.add(ztreeView);
			}
		}
		return InvokeResult.success(JsonKit.toJson(ztreeViews));
	}

    public List<Record> getDeptUser(Integer resid) {
        if(resid!=null){
            List<Record> list = Db.find("select t.*, (case when t.id in (select ru.user_id from res_user ru where ru.res_id = ?) then 1 else 0 end) as selected from (select concat('d', d.id) as id, d.`name`, concat('d',d.pid) as pid from sys_dept d union all select u.id,u.`name`,concat('d', u.deptids) as pid from sys_user u where u.deptids != '') t order by convert(t.name using gbk)",resid);
            return list;
        }
        return Lists.newArrayList();
    }


    /**
     * 获取用户菜单列表
     * @param uid
     * @param type
     * @return
     */
    public List<SysRes> getUserResList(int uid,Integer type){
        //List<SysRes> resList = CacheKit.get(CacheName.userModuleCache, "getUserResList_"+uid+"_"+type);
        List<SysRes> resList = new ArrayList<>();
        if(resList == null||resList.size() == 0){
            if(type!=null){
                resList= SysRes.dao.find("SELECT * from sys_res where id in (SELECT pid from sys_res where id in ( SELECT res_id FROM res_user WHERE user_id = "+uid+" ) AND type = "+type+" AND STATUS = 1 ) union SELECT * FROM sys_res WHERE id IN ( SELECT res_id FROM res_user WHERE user_id = "+uid+" ) AND type = "+type+" AND STATUS = 1 ");
            }else{
                resList= SysRes.dao.find("SELECT * from sys_res where id in (SELECT pid from sys_res where id in ( SELECT res_id FROM res_user WHERE user_id = "+uid+" ) AND  STATUS = 1 ) union SELECT * FROM sys_res WHERE id IN ( SELECT res_id FROM res_user WHERE user_id = "+uid+" )  AND STATUS = 1 ");
            }
        }
        //CacheKit.put(CacheName.userModuleCache, "getUserResList_"+uid+"_"+type, resList);
        return resList;
    }
}
